﻿using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using KCLIMTrading.Mgmt;

namespace KCLIMTrading
{
	public partial class Form1 : Form
	{
		private B2BManager manager;
		private List<PurchaseOrder> pos = new List<PurchaseOrder>();
		private ErrorLog error = new ErrorLog();
		private TextWriter writer;

		public Form1()
		{
			InitializeComponent();

			TodayDate.Value = DateTime.Now;
			//TodayDate.ReadOnly = true;
			CurrentInvoiceNo.ReadOnly = true;
			//Input_Date.ReadOnly = true;
			Input_Branch.ReadOnly = true;
			Input_Invoice.ReadOnly = true;
			Input_PO.ReadOnly = true;
		}
		void Form1Load(object sender, EventArgs e)
		{
			writer = new ConsoleStreamWriter(toolStripStatusLabel1);
			System.Console.SetOut(writer);
			
			System.Console.WriteLine("get all pending PO from web...");
			//TextWriterTraceListener trace = (TextWriterTraceListener)System.Diagnostics.Debug.Listeners[1];
			//trace.T
			
			//TODO: determine internet is connected and user name and password is correct
			manager = new B2BManager();

			//TODO: make a button to call or automatic load everytime form application launch
			manager.GetPendingPO();
			dataGrid1.DataSource = manager.Database.PurchaseOrders;
		}
		void Form1FormClosed(object sender, FormClosedEventArgs e)
		{
			manager.Database.Save();
		}

		#region Methods
		private void PrintFile()
		{
			try
			{
				System.Console.WriteLine("testing print the first PO");
				PrintDialog dialog = new PrintDialog();
				dialog.Document = manager.PrintDocument;
				if (dialog.ShowDialog() == DialogResult.OK)
					//testing print the first PO
					manager.Print(pos[0]);
			}

			catch (Exception ex)
			{
				error.WriteToLog(ex.ToString());
			}
		}
		private void BindChart(int option)
		{
			switch(option)
			{
				default:
				case 0:
					BindWeeklyChart();
					break;
				case 1:
					BindMonthlyChart();
					break;
				case 2:
					BindPieChart();
					break;
			}
			
		}
		/// <summary>
		/// Show weekly sales in line chart.
		/// </summary>
		/// <remarks>
		/// TODO: Move into class library.
		/// </remarks>
		private void BindWeeklyChart()
		{
			System.Console.WriteLine("BindDailyChart");
			
			decimal[] sales = new decimal[7];
			DateTime[] days = new DateTime[7];
			DateTime today = DateTime.Now;
			int diffDayToSunday = (int)today.DayOfWeek;//sunday is 0
			DateTime sunday = today.AddDays(-diffDayToSunday);
			System.Console.WriteLine("sunday: "+sunday);
			DateTime current = sunday;
			
			//TODO: swap looping method to improve performance
			for(int i=0;i<7;i++)
			{
				current = current.AddDays(1);
				decimal sum = 0m;
				foreach(PurchaseOrder po in manager.Database.PurchaseOrders)
				{
					if(po.DeliveryDate.Year == current.Year
					   && po.DeliveryDate.Month == current.Month
					   && po.DeliveryDate.Day == current.Day)
						sum += po.Total;
				}
				days[i] = current;
				sales[i] = sum;
				System.Console.WriteLine(current.ToShortDateString()+": "+sum);
			}
			
			//adding point into chart control
			chart1.Series["Sales"].Points.Clear();
			//chart1.Series["Sales"].Points.AddY(sales);
			chart1.Series["Sales"].Points.DataBindXY(days,sales);
			chart1.Series["Sales"].ChartType = SeriesChartType.Column;//Line
			chart1.Series["Sales"].IsValueShownAsLabel = true;
		}
		/// <summary>
		/// Show monthly sales in line chart.
		/// </summary>
		private void BindMonthlyChart()
		{
			System.Console.WriteLine("BindMonthlyChart");
			
			string[] months = new String[12]{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug","Sep", "Oct", "Nov", "Dec"};
			decimal[] sales = new decimal[12];
			
			DateTime today = DateTime.Now;
			for(int i=0;i<12;i++)
			{
				decimal sum = 0m;
				foreach(PurchaseOrder po in manager.Database.PurchaseOrders)
				{
					if(po.DeliveryDate.Year == today.Year
					   && po.DeliveryDate.Month-1 == i)
						sum += po.Total;
				}
				sales[i] = sum;
				System.Console.WriteLine("month "+i+": "+sum);
			}
			
			//adding point into chart control
			chart1.Series["Sales"].Points.Clear();
			chart1.Series["Sales"].Points.DataBindXY(months,sales);
			chart1.Series["Sales"].ChartType = SeriesChartType.Column;//Line
			chart1.Series["Sales"].IsValueShownAsLabel = true;
		}
		/// <summary>
		/// Show top items sales.
		/// </summary>
		private void BindPieChart()
		{
			System.Console.WriteLine("BindPieChart");

			Dictionary<string, decimal> dictionary = new Dictionary<string, decimal>();
			foreach(Product product in manager.Database.Products)
				dictionary.Add(product.Name,0);
			
			//loop latest 100 days only
			DateTime today = DateTime.Now;
			foreach(PurchaseOrder po in manager.Database.PurchaseOrders)
			{
			  TimeSpan diff = today.Subtract(po.DeliveryDate);
			  if(diff.Days > 100) break;
			  
				foreach(Item item in po.Items)
				{
					if(!dictionary.ContainsKey(item.Product.Name))
						dictionary.Add(item.Product.Name,0);
					dictionary[item.Product.Name] += item.NetValue*item.Quantity;
				}
			}
			
			
			//only display top 10 or 20 products
			List<string> names = new List<string>();
			List<decimal> prices = new List<decimal>();
			List<Product> topProducts = new List<Product>();
			foreach(KeyValuePair<string,decimal> pair in dictionary)
			{
			  Product product = new Product();
			  product.Name = pair.Key;
			  product.Price = pair.Value;
			  topProducts.Add(product);
			}
			
			//sort price desc
			PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(Product));
			PropertyDescriptor property = properties.Find("Price",false);
			topProducts.Sort(new PropertyComparer<Product>(property, ListSortDirection.Descending));
			for(int i=0;i<Math.Min(20,topProducts.Count);i++)
			{
			  names.Add(topProducts[i].Name);
			  prices.Add(topProducts[i].Price);
			  System.Console.WriteLine(topProducts[i].Name+": "+topProducts[i].Price);
			}
			
			//adding point into chart control
			chart1.Series["Sales"].Points.Clear();
			chart1.Series["Sales"].Points.DataBindXY(names,prices);
			chart1.Series["Sales"].ChartType = SeriesChartType.Pie;
			chart1.Series["Sales"].IsValueShownAsLabel = true;
		}
		#endregion

		#region Events
		private void PrintButton_Click(object sender, EventArgs e)
		{
			PrintFile();
		}

		private void DeliveryDate_CheckedChanged(object sender, EventArgs e)
		{
			//Input_Date.ReadOnly = false;
			Input_Branch.ReadOnly = true;
			Input_Invoice.ReadOnly = true;
			Input_PO.ReadOnly = true;
		}
		private void PurchaseOrder_CheckedChanged(object sender, EventArgs e)
		{
			//Input_Date.ReadOnly = true;
			Input_Branch.ReadOnly = true;
			Input_Invoice.ReadOnly = true;
			Input_PO.ReadOnly = false;
		}
		private void InvoiceNum_CheckedChanged(object sender, EventArgs e)
		{
			//Input_Date.ReadOnly = true;
			Input_Branch.ReadOnly = true;
			Input_Invoice.ReadOnly = false;
			Input_PO.ReadOnly = true;
		}
		private void BranchNumber_CheckedChanged(object sender, EventArgs e)
		{
			//Input_Date.ReadOnly = true;
			Input_Branch.ReadOnly = false;
			Input_Invoice.ReadOnly = true;
			Input_PO.ReadOnly = true;
		}
		private void SearchButton_Click(object sender, EventArgs e)
		{
			if (DeliveryDate.Checked)
			{
				//Input_Date.Clear();
			}

			if (PurchaseOrder.Checked)
			{
				Input_PO.Clear();
			}

			if (InvoiceNum.Checked)
			{
				Input_Invoice.Clear();
			}
		}

		private void ProductListToolStripMenuItemClick(object sender, EventArgs e)
		{
			ProductForm form = new ProductForm(manager);
			//form.ParentForm = this;
			form.ShowDialog();
		}
		void TabControl1SelectedIndexChanged(object sender, EventArgs e)
		{
			if(tabControl1.SelectedIndex == 1)
				BindChart(0);
		}
		void RadioButton1Click(object sender, EventArgs e)
		{
			BindChart(Convert.ToInt32((sender as RadioButton).Tag));
		}

		private void PrintToolStripMenuItemClick(object sender, EventArgs e)
		{
			PrintFile();
		}
		private void ExitToolStripMenuItemClick(object sender, EventArgs e)
		{
			this.Close();
		}
		#endregion
	}
}